﻿#include "command.h"
#include <QProcess>
#include <QDebug>

Command::Command(QObject *parent) : QObject(parent)
{

}


/**
 * 单例模式
 * @brief Single::GetInstance
 * @return
 */
Command& Command::INSTANCE()
{
    /**
     * 局部静态特性的方式实现单实例。
     * 静态局部变量只在当前函数内有效，其他函数无法访问。
     * 静态局部变量只在第一次被调用的时候初始化，也存储在静态存储区，生命周期从第一次被初始化起至程序结束止。
     */
    static Command single;
    return single;
}


bool Command::isRoot(){
    QString content = Command::INSTANCE().cmdWithContent("echo", new QString[1]{"$UID"}, 1);
    return content == "0";
}


/**
 * 命令是否存在
 * @param command
 * @return
 */
bool Command::isCommandExist(const QString& command){
    QProcess process(this);
#ifdef WIN32
    process.setProgram("cmd");
    QStringList argument("/c");
    argument << command;
    argument << " --version";
    process.setArguments(argument);
#else
    process.setProgram(command);
    QStringList argument("--version");
    process.setArguments(argument);
#endif
    process.start();
    process.waitForStarted();
    process.waitForFinished();
    QProcess::ExitStatus status = process.exitStatus();
    process.kill();
    process.close();
    if(status == QProcess::ExitStatus::NormalExit){
        return true;
    }
    return false;
}



/**
 * 执行命令
 * @param command
 * @return
 */
bool Command::cmd(const QString& command, const QString* arg, const int len){
    QProcess process(this);
#ifdef WIN32
    process.setProgram("cmd");
    QStringList argument("/c");
    argument << command;
    if(arg != NULL){
        for(int i = 0; i < len; i++){
            if(arg[i].contains(" ")){
                argument << ("\"" + arg[i] + "\"");
                continue;

            }
            argument << arg[i];
        }
    }
#else
    process.setProgram(command);
    QStringList argument;
    if(arg != NULL){
        for(int i = 0; i < len; i++){
            if(arg[i].contains(" ")){
                argument << ("\"" + arg[i] + "\"");
                continue;

            }
            argument << arg[i];
        }
    }
#endif
    process.setArguments(argument);
    process.setReadChannel(QProcess::StandardOutput);
    QObject::connect(&process, &QProcess::readyReadStandardOutput, [&]() {
        QByteArray output = process.readAllStandardOutput();
        QString result = QString::fromLocal8Bit(output);
//        QString result = QString::fromUtf8(output);
        // 处理输出结果
        if(result.size() < 1){
            return;
        }
        qDebug() << result.toLocal8Bit().data();
//        qDebug() << result.toUtf8().data();
    });

    process.start();
    process.waitForStarted(-1);
    process.waitForFinished(-1);
    QProcess::ExitStatus status = process.exitStatus();
    process.kill();
    process.close();
    if(status == QProcess::ExitStatus::NormalExit){
        return true;
    }
    return false;
}




/**
 * 执行命令
 * @param command
 * @return
 */
bool Command::cmd(const QString& command){
    QString c = command;
    if(!isRoot()){
        c = "sudo " + command;
    }
    QStringList cmds = c.split(" ");
    QString * args = new QString[cmds.size() - 1];
    for(int i = 0; i < cmds.size() - 1; i++){
        args[i] = cmds.at(i + 1);
    }
    return cmd(cmds.at(0), args, cmds.size() - 1);
}




/**
 * 执行命令 并返回命令内容
 * @param command
 * @return
 */
QString Command::cmdWithContent(const QString& command, const QString* arg, const int len){
    QProcess process(this);
#ifdef WIN32
    process.setProgram("cmd");
    QStringList argument("/c");
    argument << command;
    if(arg != NULL){
        for(int i = 0; i < len; i++){
            if(arg[i].contains(" ")){
                argument << ("\"" + arg[i] + "\"");
                continue;

            }
            argument << arg[i];
        }
    }
#else
    process.setProgram(command);
    QStringList argument;
    if(arg != NULL){
        for(int i = 0; i < len; i++){
            if(arg[i].contains(" ")){
                argument << ("\"" + arg[i] + "\"");
                continue;

            }
            argument << arg[i];
        }
    }
#endif
    process.setArguments(argument);
    process.setReadChannel(QProcess::StandardOutput);
    process.start();
    process.waitForStarted(-1);
    process.waitForFinished(-1);
//    QString out = process.readAllStandardOutput();
    QByteArray output = process.readAllStandardOutput();
    QString result = QString::fromLocal8Bit(output);
    process.kill();
    process.close();
    return result;
}

